﻿#include "engine.h"
#include "bar_generator.h"

using namespace lt;

// 注册tick数据接收器，绑定代码和接收器对象
void subscriber::regist_tick_receiver(const code_t& code, tick_receiver* receiver)
{
    auto it = _engine._tick_receiver.find(code);
    if (it == _engine._tick_receiver.end())
    {
        // 如果代码尚未被注册，创建新的接收器集合
        _engine._tick_receiver[code].insert(receiver);
    }
    else
    {
        // 如果代码已被注册，将接收器加入集合
        it->second.insert(receiver);
    }
    // 增加tick引用计数
    _engine._tick_reference_count[code]++;
}

// 注销tick数据接收器，解除代码和接收器对象的绑定
void unsubscriber::unregist_tick_receiver(const code_t& code, tick_receiver* receiver)
{
    auto it = _engine._tick_receiver.find(code);
    if (it == _engine._tick_receiver.end())
    {
        return;
    }
    auto s_it = it->second.find(receiver);
    if (s_it != it->second.end())
    {
        // 从接收器集合中移除接收器
        it->second.erase(s_it);
    }
    if (it->second.empty())
    {
        // 如果接收器集合为空，删除该代码的接收器映射
        _engine._tick_receiver.erase(it);
    }
    // 减少tick引用计数
    auto d_it = _engine._tick_reference_count.find(code);
    if (d_it != _engine._tick_reference_count.end())
    {
        if(d_it->second > 0)
        {
            d_it->second--;
        }
    }
}

// 注册tape数据接收器，绑定代码和接收器对象
void subscriber::regist_tape_receiver(const code_t& code, tape_receiver* receiver)
{
    auto it = _engine._tape_receiver.find(code);
    if (it == _engine._tape_receiver.end())
    {
        _engine._tape_receiver[code].insert(receiver);
    }
    else
    {
        it->second.insert(receiver);
    }
    // 增加tick引用计数
    _engine._tick_reference_count[code]++;
}

// 注销tape数据接收器，解除代码和接收器对象的绑定
void unsubscriber::unregist_tape_receiver(const code_t& code, tape_receiver* receiver)
{
    auto it = _engine._tape_receiver.find(code);
    if (it == _engine._tape_receiver.end())
    {
        return;
    }
    auto s_it = it->second.find(receiver);
    if (s_it != it->second.end())
    {
        // 从接收器集合中移除接收器
        it->second.erase(s_it);
    }
    if (it->second.empty())
    {
        // 如果接收器集合为空，删除该代码的接收器映射
        _engine._tape_receiver.erase(it);
    }
    // 减少tick引用计数
    auto d_it = _engine._tick_reference_count.find(code);
    if (d_it != _engine._tick_reference_count.end())
    {
        if (d_it->second > 1)
        {
            d_it->second--;
        }
    }
}

// 注册bar数据接收器，并初始化bar生成器
void subscriber::regist_bar_receiver(const code_t& code, uint32_t period, bar_receiver* receiver)
{
    auto generator_iter = _engine._bar_generator[code].find(period);
    if(generator_iter == _engine._bar_generator[code].end())
    {
        // 如果bar生成器不存在，为特定周期创建新的bar生成器
        _engine._bar_generator[code][period] = std::make_shared<bar_generator>(period, _engine._ps_config->get_price_step(code));
    }
    // 添加接收器到bar生成器
    _engine._bar_generator[code][period]->add_receiver(receiver);
    // 增加tick引用计数
    _engine._tick_reference_count[code]++;
}

// 注销bar数据接收器，解除代码和接收器对象的绑定
void unsubscriber::unregist_bar_receiver(const code_t& code, uint32_t period, bar_receiver* receiver)
{
    auto it = _engine._bar_generator.find(code);
    if (it == _engine._bar_generator.end())
    {
        return;
    }
    auto s_it = it->second.find(period);
    if (s_it == it->second.end())
    {
        return;
    }
    // 从bar生成器中移除接收器
    s_it->second->remove_receiver(receiver);
    if(s_it->second->invalid())
    {
        // 如果bar生成器失效，删除该生成器
        it->second.erase(s_it);
        if (it->second.empty())
        {
            _engine._bar_generator.erase(it);
        }
    }

    // 减少tick引用计数
    auto d_it = _engine._tick_reference_count.find(code);
    if (d_it != _engine._tick_reference_count.end())
    {
        if (d_it->second > 1)
        {
            d_it->second--;
        }
    }
}

// 构造函数，初始化交易引擎及其上下文
engine::engine(context_type ctx_type,const char* config_path)
{
    _lt = lt_create_context(ctx_type, config_path);  // 创建交易上下文
    engine::_self = this;  // 设置静态self指针指向当前实例
    lt_bind_realtime_event(_lt, order_event{ _entrust_callback ,_deal_callback ,_trade_callback ,_cancel_callback ,_error_callback }, 
    _init_callback, _update_callback, _destroy_callback);  // 绑定实时事件的回调函数
    const auto& ps_config = lt_get_include_config(_lt, "price_step_config");  // 获取价格步长配置
    _ps_config = std::make_shared<price_step>(ps_config);  // 初始化价格步长对象
}

// 析构函数，销毁交易引擎上下文
engine::~engine()
{
    lt_destory_context(_lt);  // 销毁交易上下文
}

// 注册策略，将策略绑定到引擎的处理机制中
void engine::regist_strategy(const std::vector<std::shared_ptr<lt::strategy>>& strategys)
{
    subscriber suber(*this);  // 创建订阅者
    for (auto it : strategys)
    {
        // 绑定策略处理函数到引擎
        this->add_handle(it->get_id(),std::bind(&lt::strategy::handle_change, &(*it), std::placeholders::_1));
        _strategy_map[it->get_id()] = (it);  // 保存策略到映射表中
    }
}

// 清除所有已注册的策略，并清除与订单相关的策略映射
void engine::clear_strategy()
{
    this->clear_handle();  // 清除所有策略处理函数
    _estid_to_strategy.clear();  // 清除订单与策略的映射关系
    _need_check_condition.clear();  // 清除需要检查的条件
    _strategy_map.clear();  // 清空策略映射表
}

// 注册订单ID与策略ID的映射关系
void engine::regist_estid_strategy(estid_t estid, straid_t straid)
{
    _estid_to_strategy[estid] = straid;
}

// 注销订单ID与策略ID的映射关系
void engine::unregist_estid_strategy(estid_t estid)
{
    auto it = _estid_to_strategy.find(estid);
    if (it != _estid_to_strategy.end())
    {
        _estid_to_strategy.erase(it);  // 从映射表中删除订单ID
    }
}

// 设置交易过滤器，用于在下单前进行过滤
void engine::set_trading_filter(filter_function callback)
{
    _filter_function = callback;
}

// 获取指定代码的订单统计信息
const order_statistic& lt::engine::get_order_statistic(const code_t& code)const
{
    return lt_get_order_statistic(_lt,code);
}

// 下单操作，根据指定的策略ID、偏移、方向、代码、数量、价格和订单标志下单
estid_t engine::place_order(straid_t id,offset_type offset, direction_type direction, const code_t& code, uint32_t count, double_t price, order_flag flag)
{
    PROFILE_DEBUG(code.get_id());
    // 如果存在过滤器，先进行过滤
    if(_filter_function)
    {
        if(!_filter_function(code, offset, direction, count, price, flag))
        {
            LOG_WARNING("engine place order : _filter_function false", code.get_id(), offset, direction, price, count);
            return INVALID_ESTID;  // 如果过滤器返回false，不下单
        }
    }
    
    LOG_INFO("engine place order : ", code.get_id(), offset, direction, price, count);
    // 执行下单操作
    estid_t estid = lt_place_order(_lt, offset, direction, code, count,price, flag);
    if (estid != INVALID_ESTID)
    {
        // 如果下单成功，注册订单ID与策略ID的映射
        regist_estid_strategy(estid, id);
    }
    return estid;
}

// 撤单操作，尝试撤销指定订单
void engine::cancel_order(estid_t estid)
{
    LOG_DEBUG("cancel_order : ", estid);
    if (lt_cancel_order(_lt, estid))
    {
        remove_condition(estid);  // 如果撤单成功，移除该订单的条件检查
    }
    else 
    {
        if(!lt_get_order(_lt, estid).invalid())
        {
            set_cancel_condition(estid, [](estid_t estid)->bool {
                return true;  // 如果撤单失败，设置撤单条件
            });
        }
    }
}

// 获取指定代码的持仓信息
const position_info& engine::get_position(const code_t& code) const
{
    return lt_get_position(_lt, code);
}

// 获取指定订单ID的订单信息
const order_info& engine::get_order(estid_t estid) const
{
    return lt_get_order(_lt, estid);
}

// 获取最近的交易时间
daytm_t engine::get_last_time() const
{
    return lt_get_last_time(_lt);
}

// 获取收盘时间
daytm_t engine::get_close_time() const
{
    return lt_get_close_time(_lt);
}

// 设置撤单条件，将特定条件绑定到订单ID
void engine::set_cancel_condition(estid_t estid, std::function<bool(estid_t)> callback)
{
    if(estid != INVALID_ESTID)
    {
        LOG_DEBUG("set_cancel_condition : ", estid);
        _need_check_condition[estid] = callback;  // 保存订单ID和对应的条件检查回调
    }
}

// 检查并执行所有已注册的撤单条件
void engine::check_condition()
{
    for (auto it = _need_check_condition.begin(); it != _need_check_condition.end();)
    {
        if (it->second(it->first))
        {
            // 如果条件满足，尝试撤单，如果撤单成功，移除该条件
            if (lt_get_order(_lt,it->first).invalid() || lt_cancel_order(_lt, it->first))
            {
                it = _need_check_condition.erase(it);
            }
            else 
            {
                ++it;
            }
        }
        else
        {
            ++it;
        }
    }
}

// 移除特定订单ID的撤单条件
void engine::remove_condition(estid_t estid) 
{
    auto odit = _need_check_condition.find(estid);
    if (odit != _need_check_condition.end())
    {
        _need_check_condition.erase(odit);  // 从条件检查列表中删除该订单ID
    }
}

// 获取最后一次下单时间
daytm_t engine::last_order_time()
{
    return lt_last_order_time(_lt);
}

// 获取当前的交易日
uint32_t engine::get_trading_day()const
{
    return lt_get_trading_day(_lt);
}

// 获取当日市场信息
const today_market_info& engine::get_today_market_info(const code_t& code)const
{
    return lt_get_today_market_info(_lt, code);
}

// 获取接近的价格，根据价格步长进行调整
double_t engine::get_proximate_price(const code_t& code, double_t price)const
{
    if (_ps_config)
    {
        return _ps_config->get_proximate_price(code, price);  // 使用价格步长配置获取接近的价格
    }
    LOG_WARNING("_price_step_config null");
    return price;
}

// 根据tick信息判断成交方向
deal_direction engine::get_deal_direction(const tick_info& prev, const tick_info& tick)const
{
    if (tick.price >= prev.sell_price() || tick.price >= tick.sell_price())
    {
        return deal_direction::DD_UP;  // 成交价格上涨
    }
    if (tick.price <= prev.buy_price() || tick.price <= tick.buy_price())
    {
        return deal_direction::DD_DOWN;  // 成交价格下跌
    }
    return deal_direction::DD_FLAT;  // 成交价格持平
}

// 订阅tick数据和bar数据
void engine::subscribe(const std::set<code_t>& tick_data, const std::map<code_t, std::set<uint32_t>>& bar_data)
{
    lt_subscribe(_lt, tick_data, _tick_callback);  // 订阅tick数据
}

// 取消订阅tick数据和bar数据
void engine::unsubscribe(const std::set<code_t>& tick_data, const std::map<code_t, std::set<uint32_t>>& bar_data)
{
    for (auto& it : bar_data)
    {
        auto s = _bar_generator.find(it.first);
        if (s != _bar_generator.end())
        {
            for (auto& s_it : it.second)
            {
                auto a = s->second.find(s_it);
                if (a != s->second.end())
                {
                    s->second.erase(a);  // 取消bar数据的订阅
                }
            }
        }
    }
}
    